/**
 * Copyright (C) 2012 Daniel Gee.
 * See LICENSE.txt for more details.
 */
package examples;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import com.rl.dungeon.Location;
import com.rl.dungeon.builders.DefaultBuilder;
import com.rl.dungeon.pathing.AStar;
import com.rl.gui.AppearancePanel;
import com.rl.util.DiceRoller;

/**
 * Simple example of {@link AStar} doing its thing. Uses {@link AppearancePanel} for display.
 * 
 * @author Daniel Gee
 */
@SuppressWarnings("serial")
public class AStarSample extends JFrame
{
	/**
	 * 25 chars tall.
	 */
	public static final int DUNGEON_HEIGHT = 25;

	/**
	 * 80 chars wide
	 */
	public static final int DUNGEON_WIDTH = 80;

	/**
	 * 
	 * @param args
	 *            none are read.
	 */
	public static void main(String... args)
	{
		Location.setCacheEdge(Location.of(AStarSample.DUNGEON_WIDTH, AStarSample.DUNGEON_HEIGHT));

		EventQueue.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				try
				{
					AStarSample frame = new AStarSample();
					frame.setVisible(true);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public AStarSample()
	{
		// Self setup.
		this.setTitle("AStar Sample: Uses A* pathfinding (click a cell)");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Dimension currentResolution = Toolkit.getDefaultToolkit().getScreenSize();
		this.setLocation(currentResolution.width / 5, currentResolution.height / 4);
		this.setSize(655, 515);

		// A JMenubar along the top.
		JMenuBar menuBar = new JMenuBar();
		this.setJMenuBar(menuBar);
		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);
		JMenuItem mntmQuit = new JMenuItem("Quit");
		mntmQuit.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
		mnFile.add(mntmQuit);

		// Things we'll be showing.
		final AppearancePanel displayPanel = new AppearancePanel();
		displayPanel.setFont(new Font("Courier New", Font.PLAIN, 14));
		displayPanel.setLineOffset(0);

		final JLabel locationLabel = new JLabel("Location");
		final JLabel infoLabel = new JLabel("Info");
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(locationLabel, BorderLayout.NORTH);
		this.getContentPane().add(displayPanel, BorderLayout.CENTER);
		this.getContentPane().add(infoLabel, BorderLayout.SOUTH);

		final DefaultBuilder dg = new DefaultBuilder(new DiceRoller());
		final SimpleDungeon theDungeon = new SimpleDungeon(dg.generate(AStarSample.DUNGEON_WIDTH,
				AStarSample.DUNGEON_HEIGHT));
		displayPanel.setAppearanceMap(new PathFilteredScreen(null, theDungeon));

		// Mouse Input
		displayPanel.addMouseMotionListener(new MouseMotionListener()
		{

			@Override
			public void mouseDragged(MouseEvent e)
			{

			}

			@Override
			public void mouseMoved(MouseEvent e)
			{
				Location loc = displayPanel.locationOf(e.getX(), e.getY());
				locationLabel.setText("Mouse At: " + loc);
			}
		});
		displayPanel.addMouseListener(new MouseListener()
		{

			@Override
			public void mouseClicked(MouseEvent e)
			{

			}

			@Override
			public void mouseEntered(MouseEvent e)
			{

			}

			@Override
			public void mouseExited(MouseEvent e)
			{

			}

			@Override
			public void mousePressed(MouseEvent e)
			{
				final Location start = displayPanel.locationOf(e.getX(), e.getY());

				final List<Location> path = AStar.computePath(start, theDungeon.getStairs(),
						theDungeon);

				displayPanel.setAppearanceMap(new PathFilteredScreen(path, theDungeon));

				infoLabel.setText("Clicked Cell: " + start + ", R-Dist: "
						+ start.rogueDistance(theDungeon.getStairs())
						+ (path != null ? ", Path Dist: " + path.size() : ""));
			}

			@Override
			public void mouseReleased(MouseEvent e)
			{

			}
		});

		// Keyboard Input
		displayPanel.addKeyListener(new KeyAdapter()
		{
			/**
			 * Normal "keyTyped" events won't read arrow key input. So, to deal with that, we use
			 * this instead for arrow keys.
			 * 
			 * @see java.awt.event.KeyAdapter#keyPressed(java.awt.event.KeyEvent)
			 */
			@Override
			public void keyPressed(KeyEvent e)
			{
				if (e.getKeyChar() == 'n')
				{
					displayPanel.setAppearanceMap(new PathFilteredScreen(null,
							new SimpleDungeon(dg.generate(AStarSample.DUNGEON_WIDTH,
									AStarSample.DUNGEON_HEIGHT))));
				}
				else
				{

					infoLabel.setText(e.toString());
				}
				e.consume();
			}

			/**
			 * @see java.awt.event.KeyAdapter#keyReleased(java.awt.event.KeyEvent)
			 */
			@Override
			public void keyReleased(KeyEvent e)
			{
				// nothing
			}

			@Override
			public void keyTyped(KeyEvent e)
			{
				this.keyPressed(e);
			}
		});
	}
}
